package cheme.ProcessEditor.DirectEdit;

import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.requests.DirectEditRequest;
import org.eclipse.gef.tools.CellEditorLocator;
import org.eclipse.gef.tools.DirectEditManager;
import org.eclipse.jface.viewers.ICellEditorValidator;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;

import cheme.ProcessEditor.Policies.ResizeLabelRequest;

public abstract class ChemeExtendedDirectEditManager extends DirectEditManager
{
	Class editorType;
	Font figureFont;
	protected Label label;
	protected String originalValue;
	private boolean committing = false;
	protected ICellEditorValidator validator = null;
	private int sizeInset = 4;
	
	private ResizeLabelRequest resizeLabelRequest;

	/**
	 * Creates a new ActivityDirectEditManager with the given attributes.
	 * 
	 * @param source the source EditPart
	 * @param editorType type of editor
	 * @param locator the CellEditorLocator
	 */
	public ChemeExtendedDirectEditManager(GraphicalEditPart source, Class editorType, CellEditorLocator locator,
			Label label, ICellEditorValidator validator)
	{
		super(source, editorType, locator);
		this.editorType = editorType;
		this.label = label;
		this.originalValue = label.getText();
		this.validator = validator;
	}

	/**
	 * @see org.eclipse.gef.tools.DirectEditManager#bringDown()
	 */
	protected void bringDown()
	{
		Font disposeFont = figureFont;
		figureFont = null;
		super.bringDown();
		if (disposeFont != null)
			disposeFont.dispose();
	}

	/**
	 * Commits the current value of the cell editor by getting a {@link Command}
	 * from the source edit part and executing it via the {@link CommandStack}.
	 * Finally, {@link #bringDown()}is called to perform and necessary cleanup.
	 */
	protected void commit()
	{
		if (committing)
		{
			return;
		}
		
		committing = true;
		
		try
		{
			//we set the cell editor control to invisible to remove any possible flicker
			getCellEditor().getControl().setVisible(false);

			if (isDirty())
			{
				CommandStack stack = getEditPart().getViewer().getEditDomain().getCommandStack();
				Command textCmd = getEditPart().getCommand(getDirectEditRequest());
				
				if(textCmd != null && textCmd.canExecute())
				{
					stack.execute(textCmd);
				}
			}
		}
		finally
		{
			/*
			 * The command may remove the field to which the editor is attached.
			 * If so, a error will be thrown of bringdown is called after the removal--
			 * that is, executing the textCmd command.
			 * 
			 * Alas, I cannot get it to behave with simple ordering of statements... have to edit the thing.
			 */
			
			bringDown();
			
			committing = false;
		}
	}
	
	/**
	 * Creates and returns the DirectEditRequest.
	 * @return the direct edit request
	 */
	protected DirectEditRequest createDirectEditRequest() {
		DirectEditRequest req = new DirectEditRequest();
		req.setCellEditor(getCellEditor());
		req.setDirectEditFeature(getDirectEditFeature());
		return req;
	}

	/**
	 * @return the resizeLabelRequest
	 */
	protected ResizeLabelRequest getResizeLabelRequest(Point preferredSize)
	{
		if(null == resizeLabelRequest)
		{
			resizeLabelRequest = new ResizeLabelRequest(preferredSize.x + sizeInset, preferredSize.y + sizeInset);
		}
		else
		{
			resizeLabelRequest.setPreferredSize(new Dimension(preferredSize.x + sizeInset, preferredSize.y + sizeInset));
		}
		
		return resizeLabelRequest;
	}
}